package vip.liux.front.infrastructure.config;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.jwt.JwtDecoder;
import org.springframework.security.oauth2.jwt.NimbusJwtDecoder;
import org.springframework.security.web.SecurityFilterChain;

// @Configuration
public class ResourceServerConfiguration {
    @Bean
    public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        http.authorizeHttpRequests(authorizeRequests ->
                        authorizeRequests
                                // 1.1 静态资源，可匿名访问
                                .requestMatchers(HttpMethod.GET, "/**.html", "/**.css", "/**.js").permitAll()
                                // 1.2 swagger 允许匿名访问
                                .requestMatchers("/swagger-ui.html").permitAll()
                                // 1.3 webSocket SseEmitter 允许匿名访问
                                .requestMatchers("/websocket/echo").permitAll()
                                .requestMatchers("/api/sse/**").permitAll()
                                // 1.4 开放接口，允许匿名访问
                                .requestMatchers("/api/open-api/**").permitAll()
                                .anyRequest()
                                .hasAuthority("SCOPE_openid")
                )
                // oauth2Login 核心拦截器
                // 1. OAuth2LoginAuthenticationFilter: 处理授权码登录模式的回调逻辑,
                // 通过上游的 OAuth2AuthorizationCodeGrantFilter 获取 access token 和 id token,去获取用户信息, 完成单点登录逻辑
                .oauth2Login(oAuth2LoginConfigurer -> {

                })
                // oauth2Client 核心拦截器
                // 1. OAuth2AuthorizationCodeGrantFilter: 从外部登录页回调进来, 先于OAuth2LoginAuthenticationFilter处理, 并获取授权码,
                //      通过授权码获取 access token 和 id token 和 客户端注册信息并存储, 再重定向到OAuth2LoginAuthenticationFilter 完成外部客户端用户的登录国际
                // 2. OAuth2AuthorizationRequestRedirectFilter: 发起 OAuth2 授权码模式的授权请求, 重定向到授权服务器的授权端点, 并携带上OAuth2LoginAuthenticationFilter的地址,
                //      在完成授权回调后, 重定向到 OAuth2AuthorizationCodeGrantFilter 完成登录逻辑
                .oauth2Client(oAuth2ClientConfigurer -> {
                })
                .oauth2ResourceServer(resourceServerConfigurer ->
                        resourceServerConfigurer.jwt(jwtConfigurer -> {
                        })
                );
        return http.build();
    }

    @Bean
    JwtDecoder jwtDecoder(@Value("${spring.security.oauth2.resourceserver.jwt.jwk-set-uri}") String jwkSetUri) {
        return NimbusJwtDecoder.withJwkSetUri(jwkSetUri).build();
    }
}
